package xj.model.uml;

import static xj.model.uml.UMLModelConstants.ROLE_ACTIVITY_FLOW;
import static xj.model.uml.UMLModelConstants.ROLE_ACTIVITY_NODE;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import xj.meta.ModelElement;

public class ActivityDiagram extends UMLDiagram {

  public ActivityDiagram() {
    setType(DiagramType.Activity_Diagram);
  }

  public ActivityDiagram(String name) {
    super(name);
    setType(DiagramType.Activity_Diagram);
  }
  @Override
  public boolean checkAllowedEdge(ModelElement m) {
    if (m != null) { 
      if (m instanceof ActivityFlow) { 
	return true;
      } else if (m instanceof UMLAssociation) { 
	UMLAssociation a = (UMLAssociation) m;
	if (a.getType() == UMLAssociation.AssociationType.Notes_Link) { 
	  return true;
	}
      }
    }       
    return false; 
  }

  @Override
  public boolean checkAllowedNode(ModelElement m) { 
    if (m != null && 
	(m instanceof ActivityNode ||
	 m instanceof Note)) {
      return true;
    }
    return false; 
  }

  public void addActivityNode(ActivityNode s) {
    if (s != null) {
      nodes.add(s);
      addOwnedElement(s, ROLE_ACTIVITY_NODE);
    }
  }

  public void removeActivityNode(ActivityNode s) {
    if (s != null) {
      nodes.remove(s);
      removeOwnedElement(s);
    }
  }

  public Set<ActivityNode> getActivityNodes() {
    return nodes;
  }

  public void addActivityFlow(ActivityFlow t) {
    if (t != null) {
      flows.add(t);
      addOwnedElement(t, ROLE_ACTIVITY_FLOW);
    }
  }

  public void removeActivityFlow(ActivityFlow t) {
    if (t != null) {
      flows.remove(t);
      removeOwnedElement(t);
    }
  }

  public Set<ActivityFlow> getActivityFlows() {
    return flows;
  }

  @Override
  public Object clone() throws CloneNotSupportedException {
    ActivityDiagram hs = (ActivityDiagram) super.clone();

    hs.nodes = new HashSet<ActivityNode>();
    Iterator<ActivityNode> iter1 = nodes.iterator();
    while (iter1.hasNext()) {
      ActivityNode s = iter1.next();
      hs.addActivityNode((ActivityNode) s.clone());
    }

    hs.flows = new HashSet<ActivityFlow>();
    Iterator<ActivityFlow> iter2 = flows.iterator();
    while (iter2.hasNext()) {
      ActivityFlow t = iter2.next();
      hs.addActivityFlow((ActivityFlow) t.clone());
    }

    return hs;
  }

  @Override
  public void deconstruct() {
    super.deconstruct();
    nodes.clear();
    flows.clear();
  }

  @Override
  public void add(ModelElement parent, ModelElement e, Object arg) {
    if (e != null) {
      if (e instanceof ActivityNode) {
	addActivityNode((ActivityNode) e);
      } else if (e instanceof ActivityFlow) {
	addActivityFlow((ActivityFlow) e);
      } else {
	super.add(parent, e, arg);
      }
    }
  }

  protected Set<ActivityNode> nodes = new HashSet<ActivityNode>();

  protected Set<ActivityFlow> flows = new HashSet<ActivityFlow>();

}
